package com.oocl.ita.sakura.forwarder;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;

import com.oocl.ita.sakura.client.Client;
import com.oocl.ita.sakura.handler.IHandler;
import com.oocl.ita.sakura.parser.IParser;
import com.oocl.ita.sakura.parser.ProtocolParser;
import com.oocl.ita.sakura.protocol.Protocol;
import com.oocl.ita.sakura.server.IMServer;

public class Forwarder implements Runnable {
	public static final ThreadLocal<ObjectOutputStream> threadlocaloos = new ThreadLocal<ObjectOutputStream>(); // 静态不用实例化，final只读
	public static final ThreadLocal<Client> threadlocalClient = new ThreadLocal<Client>(); // 静态不用实例化，final只读
	private Socket clientSocket;
	private IParser parser;

	public Forwarder(Socket clientSocket) {
		super();
		this.parser = new ProtocolParser();
		this.clientSocket = clientSocket;
	}

	public void run() {
		System.out.println("Forwarder : " + Thread.currentThread().getName());
		ObjectOutputStream oos = null;
		ObjectInputStream ois = null;		
		
		try {
			oos = new ObjectOutputStream(clientSocket.getOutputStream());
			oos.flush();
			ois = new ObjectInputStream(clientSocket.getInputStream());
			threadlocaloos.set(oos);

			while (true) {
				System.out.println("Forwarder " + Thread.currentThread().getName() + " : start reading protocol loop");
				Protocol protocol = (Protocol) ois.readObject();
				System.out.println("Forwarder : ois read " + protocol);
				IHandler handler = parser.parse(protocol);
				handler.handle(protocol);
			}
		} catch (SocketException e) {
			/*
			 *  处理客户端断线
			 *  1. 打印报错
			 *  2. 从ClientOOSMap中移除Client 
			 */
			System.out.println("============================");
			System.out.println("Forwarder " + Thread.currentThread().getName() + " : may be someone lose connetion");
			IMServer.removeClient(threadlocalClient.get());
			System.out.println("Forwarder : remove the client lost connection : size of clientOOSmap   " + IMServer.getClientOosMap().size());
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}
}
